<?php
namespace App\Common\Lib\Err\BaseException;

use App\Common as com;
use App\Common\Lib\Err\BaseException\Throw_ as nameThrow_;

class Throw_ extends \Exception {

	protected array $data = [];

	protected array $privacy = [];

	public function setData( $errData ){
		$this->data = $errData;
	}

	public function getData(){
		return $this->data;
	}

	/**
	 * 设置私密
	 * @param $privacyData
	 * @return void
	 */
	public function setPrivacyData( $privacyData ){
		$this->privacy = $privacyData;
	}

	/**
	 * @return mixed
	 */
	public function getPrivacyData(){
		return $this->privacy;
	}

	/**
	 * 记录到日志
	 * @return $this
	 */
	public function recordLog(  ):self {
		return $this;
	}

	// ===============================
	//
	//
	// 下面为静态方法
	//
	//
	// ===============================

	/**
	 * 构建异常
	 * @param string $msg 错误说明。[null][默认]没有
	 * @param int $code 错误码
	 * @param array $data 其他数据
	 * @return $this
	 */
	public static function makeOfNew( string $msg, int $code = 0, array $data = [], array $privateData = [] ):self {
		return self::getThrow( $msg, $code, [
			'data' => $data,
			'privateData' => $privateData,
		] );
	}

	/**
	 * 抛出异常，级别：严重
	 * @param string $msg 错误说明。[null][默认]没有
	 * @param int $code 错误码
	 * @param array $data 其他数据
	 * @return $this
	 */
/*	public static function severity( string $msg, int $code = 0, array $data = [] ):self {
		$param['data'] = $data;
		$param['data']['level'] = self::$exceptionLevel_Severity;
		return self::throwManage( $msg, $code, $param );
	}*/

	/**
	 * 抛出异常
	 * @param string $msg 错误说明。[null][默认]没有
	 * @param int $code 错误码
	 * @param array $param 参数数组 <br />
	 * ················· [可空](array)	$param['data']	说明：其他数据	<br />
	 * ················· [可空](array)	$param['privateData']	说明：私有数据(不公开)	<br />
	 * ················· [可空/多选_A/必须](unknown_type)	$param['AAAAA']	说明：AAAAA	<br />
	 * @return $this
	 */
	public static function getThrow( string $msg, int $code = 0, array $param = [] ):self {
		// ...
		$param['data'] = $param['data'] ?? [];
		$param['privateData'] = $param['privateData'] ?? [];
		// 替换
		if( strpos( $msg, '{msg}' ) !== false ){
			$codeStr = com\Lib\Err\Code::getUserText( $code );
			$msg = str_replace( '{msg}', $codeStr, $msg );
		}
		//
		if( empty( $msg ) ){
			$codeStr = com\Lib\Err\Code::getUserText( $code );
			if( $codeStr !== '' ) {
				$msg .= $codeStr;
			}
		}
		//
		$exception = new static( $msg, $code );
		//
		$param['data']['errInfo'] = self::buildErrData( $msg, $code, $param );
		//
		if( ! empty( $param['data'] ) ) $exception->setData( $param['data'] );
		if( ! empty( $param['privateData'] ) ) $exception->setPrivacyData( $param['privateData'] );
		//
		return $exception;
	}

	/**
	 * 生成错误信息
	 * @param string $msg 错误说明。[null][默认]没有
	 * @param int $code 错误码
	 * @param array $param
	 * @return array 错误信息
	 */
	protected static function buildErrData( string $msg, int $code = 0, array $param = [] ){
		$debug_backtrace = debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS, 4 );
		return [
			'code' => $code,
			'codeStr' => com\Cla\Err\Code::getUserText( $code ),
			'msg' => $msg,
			'param' => $param['data'],
			'file' => $debug_backtrace[3]['file'] ?? '',
			'line' => $debug_backtrace[3]['line'] ?? '',
		];
	}

	/**
	 * 执行闭包，如果抛出异常（com\Lib\Err\Exception\Throw_），则返回异常code，其他异常则重新抛出
	 * @param \Closure $function 执行的闭包
	 * @return mixed 闭包的返回值
	 */
	public static function callFunTryOrReCode( \Closure $function ) {
		try {
			return $function();
		}catch( \Exception $e ){
			return $e->getCode();
		}
	}

}
